# coding=utf-8
import datetime
import json
import re

from rest_framework import serializers


class AllowNullDateTimeField(serializers.DateTimeField):
    """允许为空的时间序列化字段"""

    def to_internal_value(self, value):
        if not value and self.required is False:
            return None

        if value == '0000-00-00 00:00:00':
            return None

        if isinstance(value, int):
            if len(str(value)) == 10:
                return datetime.datetime.utcfromtimestamp(value)
            elif len(str(value)) == 13:
                return datetime.datetime.utcfromtimestamp((int(value / 1000)))
        elif isinstance(value, str):
            if re.match(r'^\d+$', value):
                if len(value) == 10:
                    return datetime.datetime.utcfromtimestamp(int(value))
                elif len(value) == 13:
                    return datetime.datetime.utcfromtimestamp((int(int(value) / 1000)))
            elif re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}\+08:00$', value):
                value = re.findall(r'^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6})\d{3}\+08:00$', value)[0]
                return datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f')
            elif re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}\+08:00$', value):
                return datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f+08:00')
            elif re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+08:00$', value):
                return datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S+08:00')
            elif re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$', value):
                return datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%SZ')
            elif re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.{\d+}$', value):
                value = value.split('.')[0]
                return datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')
            elif re.match(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$', value):
                return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
            elif re.match(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.{\d+}$', value):
                value = value.split('.')[0]
                return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')

        return super(AllowNullDateTimeField, self).to_internal_value(value)


class AllowNullDateField(serializers.DateField):
    def to_internal_value(self, value):
        if not value and self.required is False:
            return None

        if isinstance(value, str):
            if re.match(r'^\d{4}-\d{2}-\d{2}$', value):
                return datetime.datetime.strptime(value, '%Y-%m-%d').date()

            elif re.match(r'^\d{4}\\\d{2}\\\d{2}$', value):
                return datetime.datetime.strptime(value, '%Y\\%m\\%d').date()

        return super(AllowNullDateField, self).to_internal_value(value)


class FloatField(serializers.FloatField):
    def to_internal_value(self, data):
        if isinstance(data, str) and len(data) > self.MAX_STRING_LENGTH:
            self.fail('max_string_length')

        try:
            return float(data)
        except (TypeError, ValueError):
            return 0.0


class ListField(serializers.ListField):
    def to_internal_value(self, data):
        if data is None:
            return None

        ret = super().to_internal_value(data)

        return json.dumps(ret)

    def to_representation(self, data):
        if data:
            if isinstance(data, str):
                try:
                    data = json.loads(data)
                except Exception as _:
                    data = []
            elif not isinstance(data, list):
                data = []
        else:
            data = []

        return super().to_representation(data)


class DictField(serializers.DictField):
    def to_internal_value(self, data):
        if data is None:
            return None
        return json.dumps(super().to_internal_value(data))

    def to_representation(self, data):
        if data:
            if isinstance(data, str):
                try:
                    data = json.loads(data)
                except Exception as _:
                    data = {}

            elif not isinstance(data, dict):
                data = {}
        else:
            data = {}

        return super().to_representation(data)